Technical Note TN2040
Apple Image Capture Camera Module changes for Mac OS X Update 10.1.3

目次

このテクニカルノートでは、Mac OS X Update 10.1.3 の Apple Image Capture カメラモジュールの変更点について説明します。

[2002 年 4 月 16 日]






新しい階層ツリー構造

アップルの Image Capture Architecture は、オブジェクトとプロパティという 2 つの主要な要素がベースになっています(詳細については、Image Capture SDK マニュアルを参照してください)。オブジェクトは、他のオブジェクトへの参照を含むことでツリー構造を形成し、プロパティを持つことができます。

Mac OS X の Apple Image Capture のカメラモジュールは、フラットな(階層型ではない)オブジェクト構造のみを実装していました。デバイスのすべての画像を取得するには、次のようにデバイスオブジェクト(ICAObject 型)の ICAGetChildCount 関数を呼び出すだけで十分でした。



リスト 1 デバイスツリーを渡り歩くための従来のテクニック

void ParseObjectHierarchy(ICAObject deviceObject)
{
    ICAGetChildCountPB getChildCountPB;
    OSErr err;

    memset(&getChildCountPB, 0, sizeof(ICAGetChildCountPB));
    getChildCountPB.object = deviceObject;
        /* このデバイスの子の数を取得する */
    err = ICAGetChildCount(&getChildCountPB, nil);
    if (err == noErr)
    {
        UInt32 index;

            /* 各子オブジェクトに対して反復処理を実行する */
        for (index = 0; index < getChildCountPB.count; ++index)
        {
          /* 各子オブジェクトを処理するコードをここに追加する */
        }
    }

}


Mac OS X Update 10.1.3 の Image Capture では、フラットな ICAObject 構造体は、新しい階層ツリー構造に変更されました。そのため、オブジェクト階層を渡り歩いて、指定のデバイスのすべてのオブジェクトを探し出すには、上記のコードでは不十分になりました。

指定されたデバイスの画像、ムービー、オーディオファイルをすべて取得するには、現在、2 つの選択肢があります。一連の ICAGetChildCount/ICAGetNthChild 関数の呼び出しを発行し、デバイスツリーを渡り歩くやり方と、デバイスオブジェクトに ICACopyObjectPropertyDictionary 関数を使って、すべてのオブジェクトの "data" 配列と "tree" ディレクトリを取得するやり方です。

下記のリスト 2 は、一連の ICAGetChildCount/ICAGetNthChild 関数の呼び出しを発行して、デバイスツリーを渡り歩くためのコードを示します。



リスト 2 デバイスツリーを渡り歩く新しいテクニック

void ParseObjectHierarchy(ICAObject object)
{
    UInt32 imageCount;
    UInt32 imageCountIndex;

    imageCount = GetNumberOfChildrenForObject (object);
    /* 指定された親オブジェクトのオブジェクト階層に対して反復処理を実行する */
    for (imageCountIndex = 0; imageCountIndex <
                            imageCount; ++imageCountIndex)
    {
        ICAObject      childObject;
        ICAGetChildCountPB getChildCountPB;
        OSErr          result;

        /* 次の子オブジェクトを取得する */
        childObject = getNthChild(object, imageCountIndex);
        if (childObject == NULL)
            break;

        memset(&getChildCountPB, 0, sizeof(ICAGetChildCountPB));
        getChildCountPB.object = childObject;
        result = ICAGetChildCount(&getChildCountPB, nil);
            /* 子の数が 0 の場合、それ以上子は存在しないので
               オブジェクト階層の解析を停止し、このオブジェクトの
               画像データを取得する */
        if (getChildCountPB.count == 0)
        {
           /* 子オブジェクトを処理するコードをここに追加する */
        }
        else
          /* このオブジェクトには子があるため、現在のオブジェクトを
             新しい親として使い、新しい階層を渡り歩く */
        {
        ParseObjectHierarchy (childObject);
        }
    }
}


もう 1 つの方法として、デバイスオブジェクトに ICACopyObjectPropertyDictionary 関数を使うやり方があります。ICACopyObjectPropertyDictionary 関数は、ICAObject 構造体をフラットにして表す、"data" 配列を含んだ Mac OS Core Foundation の CFDictionary を返します(CFArrayGetCount または NSDictionary の count メソッドを使って、ファイル数を取得します)。

さらに、Mac OS X Update 10.1.3 では、返されたディレクトリに、階層的なオブジェクトツリー全体を表現する "tree" ディレクトリが含まれる予定です。

次のリスト 3 は、ICACopyObjectPropertyDictionary 関数によって返された辞書の "data" 配列を使って、すべてのオブジェクトのリストを取得するためのコードを示します。



リスト 3 ICACopyObjectPropertyDictionary 関数によって返された辞書の "data" 配列を使って、すべてのオブジェクトのリストを取得する

OSErr ParseDeviceObjects (ICAObject deviceObject)
{
    OSErr                       err = noErr;
    ICACopyObjectPropertyDictionaryPB   dictionaryPB;
    CFDictionaryRef                 dict = NULL;
    CFArrayRef                  objectArray = NULL;
    CFIndex                     objectCount = 0, index;

    memset(&dictionaryPB, 0, sizeof(ICACopyObjectPropertyDictionaryPB));
    dictionaryPB.object     = deviceObject;
    dictionaryPB.theDict    = &dict;
    err = ICACopyObjectPropertyDictionary(&dictionaryPB, nil);
    if (err != noErr) goto bail;

        /* 'data' 辞書を取得する */
    objectArray = (CFArrayRef)CFDictionaryGetValue(dict, CFSTR("data"));
    if (objectArray ==  NULL) goto bail;

        /* オブジェクト数を取得する */
    objectCount = CFArrayGetCount(objectArray);
        /* 各オブジェクトに対して反復処理を実行する */
    for (index = 0; index < objectCount; ++index)
    {
        ICAObject       object;
        CFDictionaryRef     dictRef;
        CFNumberRef     theValue;

            /* このオブジェクトの CFDictionaryRef を取得する */
        dictRef = (CFDictionaryRef)CFArrayGetValueAtIndex (objectArray,index);

            /* デバッグ時の CFShow 関数を使って、CFDictionaryRef の
            キーと値のペアをすべてダンプできる */
        CFShow(dictRef);

            /* これで、CFDictionaryRef のすべての値を抽出できるようになる。
            例として、"tsiz" というキーに対応する値を取得する方法を示す */
        theValue = (CFNumberRef)CFDictionaryGetValue(dictRef, CFSTR("tsiz"));
        if (theValue)
        {
            Boolean gotValue = false;
            SInt32  actualNumber;

            gotValue = CFNumberGetValue(theValue,
                          kCFNumberSInt32Type,&actualNumber);

        }

    /* その他の値を抽出するコードをここに追加する */
    }

 bail:
    if (dict != NULL)
        CFRelease(dict);

    return err;
}



	

先頭に戻る

 

要約

Mac OS X Update 10.1.3 では、Apple Image Capture カメラモジュールが変更されたため、デバイスオブジェクトが指定されたデバイスのすべてのオブジェクトのリストを取得するには、ICAGetChildCount 関数を呼び出すだけでは十分ではありません。このテクニカルノートで説明されているテクニックを使い、オブジェクトの階層を解析する必要があります。

先頭に戻る

参考文献

Mac OS X Core Foundation Collection Services

ダウンロード

Acrobat gif

このテクニカルノートの PDF 版

ダウンロード


先頭に戻る